package cn.itcast.order.configuration;

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.AsyncConfigurer;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * @author danDong
 * @date 2025-02-07 15:21:36
 */
@Configuration
@EnableAsync //为什么使@Async生效
// 通过实现这个接口，可以自定义异步方法的执行器（Executor）
public class AsyncConfig implements AsyncConfigurer {

    @Override
    /**
     * 这是AsyncConfigurer接口中的一个方法，用于返回一个Executor
     * Spring将使用这个Executor来执行用@Async注解标记的异步方法
     */
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数为2，即使线程池中的线程处于空闲状态，也会保留的线程数
        executor.setCorePoolSize(2);
        // 设置最大线程数为2，线程池能够容纳的最大线程数
        executor.setMaxPoolSize(2);
        // 设置队列容量为500，当所有核心线程都在忙时，额外任务将在队列中等待。
        // 如果队列也满了，并且达到了最大线程数，则根据拒绝策略来处理新任务。
        executor.setQueueCapacity(500);
        // 设置线程名称前缀，这样你可以更容易地在日志中识别出哪些线程是由这个执行器创建的
        executor.setThreadNamePrefix("AsyncExecutor-");
        /**
         * 在Spring Boot中，这通常不是必需的，因为当ThreadPoolTaskExecutor作为bean被创建时，Spring会自动调用初始化方法。
         * 但是，如果你手动创建ThreadPoolTaskExecutor实例并打算在配置类中返回它，那么你需要显式地调用initialize()方法。
         */
        executor.initialize();
        return executor;
    }
}
